/**
 * Created by chenjt on 2017/6/16.
 * 公用装饰器
 */

/**
 * 如果一个类的成员属性采用此装饰器，那么当此类的实例对象的该属性的值发生改变时（与旧值不同时），将会执行类中定义的change事件
 * 举例如下：
 * class Person {
 *   @OnChange()
 *   public name: string;
 *   constructor() {
 *   }
 *
 *   public nameChange: EventEmitter<string> = new EventEmitter<string>();
 * }
 * const p = new Person();
 * 但我们尝试给p对象的name属性赋值时，那么nameChange方法将会被传入name的新值调用
 * p.name = 'chenjt' nameChange将自动emit发射一个值
 * @param defaultValue
 * @returns {(target:any, propertyKey:string)=>void}
 * @constructor
 */
export function OnChange(defaultValue?: any): any {
  const sufix = 'Change';
  return function OnChangeHandler(target: any, propertyKey: string): void {
    const _key = ` __${propertyKey}Value`;
    Object.defineProperty(target, propertyKey, {
      get(): any {
        return this[_key];
      },
      set(value: any): void {
        const prevValue = this[_key];
        this[_key] = value;
        if (prevValue !== value && this[propertyKey + sufix]) {
          this[propertyKey + sufix].emit(value);
        }
      }
    });
  };
}
